import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';

export default class ThreeScene {
    scene: THREE.Scene;
    camera: THREE.PerspectiveCamera;
    renderer: THREE.WebGLRenderer;
    controls: OrbitControls;
    width: number;
    height: number;
    updateList:Array<Function> = [];
  constructor(width:number, height:number,target:HTMLElement) {
    this.width = width;
    this.height = height;
    this.scene = new THREE.Scene();
    this.camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 1000);
    this.renderer = new THREE.WebGLRenderer();
    target.appendChild(this.renderer.domElement);

    const light = new THREE.AmbientLight(0xffffff);
    this.scene.add(light);

    this.camera.position.set(0,0,200);
    this.camera.lookAt(new THREE.Vector3(0,0,0));
    this.renderer.setSize(width, height);
    this.renderer.setClearColor(0x000000);

    const directionalLight = new THREE.DirectionalLight(0xffffff,1); //第二个是光照强度
    directionalLight.position.set(this.camera.position.x,this.camera.position.y,this.camera.position.z);
    this.scene.add(directionalLight);



    this.controls = new OrbitControls(this.camera, this.renderer.domElement);
    this.controls.enableDamping = true;
    this.controls.enableZoom = false;

    const animation = () => { 
        this.updateList.forEach(update => update());
        this.renderer.render(this.scene, this.camera);
        this.controls.update();
        requestAnimationFrame(animation);
    };

    animation();

    //注册resize监听
    window.addEventListener('resize', this.handleResize);
  }

  destroy() {
    //解注册监听
    window.removeEventListener('resize', this.handleResize);
  }

  //添加物体
  public addObject(object:THREE.Object3D) {
    this.scene.add(object);
  }

  //移除物体
  public removeObject(object:THREE.Object3D) {
    this.scene.remove(object);
    if ('dispose' in object && typeof object.dispose === 'function') {
        object.dispose();
    }
  }

  public addUpdate(update:Function) {
    this.updateList.push(update);
  }

  private handleResize = () => {
        this.renderer.setSize(this.width, this.height);
        this.camera.aspect = this.width / this.height;
        this.camera.updateProjectionMatrix();
    };
}